﻿#include "RpcController.h"
#include "XyNet/Channel/RpcSocketChannel.h"
#include "XyNet/Common/StringConverter.h"
#include "XyNet/Crypto/Crc.h"
#include "XyNet/Endpoint/RpcEndpoint.h"
#include "XyNet/Protocol/cpp/Rpc.service.h"

namespace XyNet
{
	RpcError::RpcError(int code, const string& name, const string& brief)
		: _code(code), _name(name), _brief(brief) {}

	string RpcError::getInfo() const
	{
		boost::format f("RpcError %08X %s:\n%s\n%s");
		f % _code % _name % _brief % _detail;
		return f.str();
	}

	//////////////////////////////////////////////////////////////////////////

	RpcController::RpcController(RpcSocketChannel* socketChannel)
		: _socketChannel(socketChannel) {}

	RpcController::~RpcController() {}

	shared_ptr<RpcChannel> RpcController::getChannel()
	{
		return _socketChannel->shared_from_this();
	}

	shared_ptr<RpcBroadcastChannel> RpcController::createBroadcastChannel()
	{
		return _socketChannel->getEndpoint()->createBroadcastChannel();
	}

	const Id& RpcController::getSocketChannelId() const
	{
		return _socketChannel->getId();
	}

	shared_ptr<RpcServiceManager> RpcController::getSocketChannelServiceManager()
	{
		return _socketChannel->getServiceManager();
	}

	void RpcController::clearUserDataAndService()
	{
		_socketChannel->clearUserDataAndService();
	}

	bool RpcController::isFailed() const
	{
		return _error && !!_error->getCode();
	}

	void RpcController::setFailed(int code, const string& detail)
	{
		assert(code != 0);
		_error = createError(code);
		_error->setDetail(detail);
	}

	shared_ptr<const RpcError> RpcController::getError() const
	{
		if (!_error)
			const_cast<RpcController*>(this)->_error = createError(0);
		return _error;
	}

	shared_ptr<RpcError> RpcController::createError(int code) const
	{
		return RpcErrors::createError(code);
	}
}